Youth Corner:

Creating a Status Bar

© 2005, David Conner

davidjc1292 at gmail dot com

Home

Tip Corner

API Corner

Youth Corner

SpriteByte: Basics

StyleBits 3

Shaped Window

Recursion

Eddie's Lessons

Beginners Programming

Help

Index


What is a Status Bar?

A Status Bar is a common control provided in Comctl32.dll included with Windows that [can be used to] display a message. Look below for an example.

How do I make a simple status bar?

It is actually very simple to create a status bar. All that you have to do is setup a resize handler, make about 4 small API calls, and setup 4 or 5 variables. This article was created to take you step by step on how to do this.

Step 1: Setting up the variables

Begin by initializing the common controls. This isn't always necessary, but it is a good idea to go ahead and initialize them, just in case. [Remember that the common controls API interface #comctl32 is pre-opened by Liberty Basic by default.]


CallDLL #comctl32, "InitCommonControls", re as void

Next you will need a handle to the window that is open. Get the handle by using:


hWnd=hwnd(#1) (or whatever the handle is in LB).  

Now, you need to set up the style variable [for the status bar]. The minimum style variable is:


style=_WS_VISIBLE or _WS_CHILD

Now give the status bar an ID. This can be any number, but I usually give mine the number 1.


id=1

After that, set up a string that will contian the message that status bar will actually display. [It is not necessary to null terminate the string]


msg$="I am a status bar!"

Step 2: Before Creating the Status Bar

Before you actually create the status bar, you will need to setup a resizehandler, which tells the window to go to a branch label when the window is resized.


#1 "resizehandler [resizeStatus]"  'instead of #1, use whatever the handle to your window is

Now you're ready to create the status bar.

Step 3: Creating the Status Bar

The API call to create the status bar is actually very simple. It is shown below, and each parameter is commented, so you know what is going on.


CallDLL #comctl32, "CreateStatusWindow",_
style as long,_ ' pass the style variable you setup before
msg$ as ptr,_ ' pass the msg$ string you created before
hWnd as long,_ ' pass the handle to the window the status bar will be on
id as long,_ ' pass the ID for the status bar
hStatus as long ' the handle to the status bar

Step 4: Setting up the Resize Branch Label

Let's say the user resizes their window. If you don't have a resizehandler activated, the statusbar won't adjust to fit the new window size. That's why we use the resizehandler code. To handle a resize of the window, you use the SendMessageA call passing it the status bar handle, the _WM_SIZE constant, and the WindowWidth variable, which will always be how wide the status bar is. The call is shown below.


CallDLL #user32, "SendMessageA",_
hStatus as long,_ ' the handle to the status bar
_WM_SIZE as long,_ ' the constant to use for the call
0 as long,_ ' nothing needed here
WindowWidth as long,_ ' the new size of the Status Bar
ret as long ' the result of the call

Make sure that this code is in the branch label you set the resizehandler to go to.

Step 5: Destroying the Status Bar

Before exiting the program, you will need to destroy the status bar. To do this call the SendMessageA and pass it the handle to the status bar and the _WM_DESTROY constant.


CallDLL #user32, "SendMessageA",_
hStatus as long,_'the status bar handle
_WM_DESTROY as long,_'the constant to use
0 as long,_'not needed
0 as long,_'not needed
ret as long'the result

Extra Things You Can Do With the Status Bar

Changing the Text on the Status Bar

To change the text on the status bar, you will need to create/change a variable or two, and call the SendMessageA API call. You first have to set up the string to tell what you want the Status Bar to change the text to.


newText$="I'm a different message!"

Now, you need to set up the constant to change the status bar. It is the SB_SETTEXT stant which is not predefined in LB. We must therefore set it up manually. The value of SB_SETTEXT is 1025 so we will make a variable that does this for us.


SB.SETTEXT = 1025

Use the SendMessageA API call to change the text. You will need to pass the status bar handle, the ID of the status bar, the SB.SETTEXT variable, and the string that contains what to change the text to.


CallDLL #user32, "SendMessageA",_
hStatus as long,_'the handle of the status bar
SB.SETTEXT as long,_'the constant to use
id as long,_'the status bar's ID
newText$ as ptr,_'the next text message
ret as long'the results of the call

Making a Multi-Part Status Bar

The purpose for the ID number is to support the use of multi-part status bars. The ID tells which part or segment of the status bar that you are trying to change. So let's create a multi-part status bar. First of all, you will need to create a struct with [the number of] segments your status bar will have. For this example, we have chosen two.


Struct prts, end1 as long, end2 as long

Next you will fill the values of the struct with the X point at which the segment will end. Always make sure that the last segment is filled with -1 so it goes all the way to the end of the window.

 
prts.end1.struct=200
prts.end2.struct=-1

Now, create a variable that contains the number of segments. This is almost always the same as the number of parts of the struct. So, for this example, it would be two.


numberOfParts=2

Next, use the SendMessageA API call to set the parts to the status bar. This requires a constant that LB doesn't recognize, so we will have to create it. The SB_SETPARTS constant has a value of 1028, so we can create a variable that is the equivalent of this.


SB.SETPARTS=1028

CallDLL #User32, "SendMessageA",_
hStatus as long,_'the handle to the status bar
SB.SETPARTS as long,_'the constant to use for this
numberOfParts as long,_'the number of parts
prts as struct,_'the struct which has the points in which to end each segment
ret as long' the results of the call

Now we get to the part where we use the ID. The first segment should be zero, the second should be 1, and so on. Fill the ID variable with the correct number, and then create a string that has the text for that segment.


ID=0
txt$="Part 1"

Now we us the SendMessageA API call to set the text. We will need to use the SB.SETTEXT variable we made earlier.


SB.SETTEXT=1025

CallDLL #user32, "SendMessageA",_
hStatus as long,_ ' the handle for the status bar
SB.SETTEXT as long,_'the constant to use
ID as long,_' the ID of the segment
txt$ as ptr,_' the text for the segment
ret as long'the result of the call

Do the part starting from the ID until you have all of the segments completed.

Final Remarks

I hope that you've learned something from this article. Status bars really aren't that hard to create and manipulate. All you need is a few API calls. By the way, if you don't really understand API calls yet, then you may want to check out Brad Moore's article in NL#101 about API calls, and about parameters and such.

[Editor: David, I appreciate the plug. I made a few minor corrections to your article and your demos (which follow). One of the biggies was the adding of a null terminator to strings passed to the API calls. Alyce actually helped me out here and I have written an article that explains when you need these and when you don't. Thanks David.]


Demo 1:


'Regular Status Bar
' by David Conner, 2005

' included for use in the status bar article

CallDLL #comctl32, "InitCommonControls", re as void ' Initialize the Common Controls

NoMainWin
WindowWidth=300:WindowHeight=300
UpperLeftX=Int((DisplayWidth-WindowWidth)/2)
UpperLeftY=Int((DisplayHeight-WindowHeight)/2)

Open "Status Bar Ex." for window as #1
    #1 "Trapclose [quit]"
    #1 "resizehandler [resizeStatus]" ' when window is resized, goto resizeStatus

    hW=hwnd(#1) ' get the handle to the window

' Set Up Variables for API Call to Create Status Bar

id=0 ' assign ID
style=_WS_VISIBLE or _WS_CHILD ' minimal style
msg$="I'm a status bar!" 

' Now Create the Status Bar

CallDLL #comctl32, "CreateStatusWindow",_
    style as long, msg$ as ptr, hW as long,_
    id as long, hStatus as long
wait

[quit]
'Destroy the Status Bar
    CallDLL #user32, "SendMessageA",_
        hStatus as long,_
        _WM_DESTROY as long,_
        0 as long,_
        0 as long,_
        ret as long

'Close Window
    Close #1
    End

[resizeStatus]
'resize the status bar
    CallDLL #user32, "SendMessageA",_
        hStatus as long,_
        _WM_SIZE as long,_
        0 as long,_
        WindowWidth as long,_
        ret as long
    wait

Demo 2

   

' Multi-part Status Bar
' by David Conner, 2005

' included for use in the status bar article

CallDLL #comctl32, "InitCommonControls", re as void ' Initialize the Common Controls

NoMainWin
WindowWidth=300:WindowHeight=300
UpperLeftX=Int((DisplayWidth-WindowWidth)/2)
UpperLeftY=Int((DisplayHeight-WindowHeight)/2)

struct prt, end1 as long, end2 as long

prt.end1.struct=200
prt.end2.struct=-1 ' make sure last one is ALWAYS -1

numberOfParts=2 ' number of parts

Open "Status Bar Ex." for window as #1
    #1 "Trapclose [quit]"
    #1 "resizehandler [resizeStatus]" ' when window is resized, goto resizeStatus

    hW=hwnd(#1) ' get the handle to the window

' Set Up Variables for API Call to Create Status Bar

id=0 ' assign ID
style=_WS_VISIBLE or _WS_CHILD ' minimal style
msg$="I'm a status bar!" 


' Now Create the Status Bar

CallDLL #comctl32, "CreateStatusWindow",_
    style as long, msg$ as ptr, hW as long,_
    id as long, hStatus as long

'make it multi-part

SB.SETPARTS=1028
SB.SETTEXT=1025

CallDLL #user32, "SendMessageA",_ ' set the multi-part
    hStatus as long,_
    SB.SETPARTS as long,_
    numberOfParts as long,_
    prt as struct,_
    ret as long

' Fill Part 2
id=1
txt$="Part 2"
Call FillPart hStatus, SB.SETTEXT, id, txt$
wait

[quit]
'Destroy the Status Bar
    CallDLL #user32, "SendMessageA",_
        hStatus as long,_
        _WM_DESTROY as long,_
        0 as long,_
        0 as long,_
        ret as long

'Close Window
    Close #1
    End

[resizeStatus]
'resize the status bar
    CallDLL #user32, "SendMessageA",_
        hStatus as long,_
        _WM_SIZE as long,_
        0 as long,_
        WindowWidth as long,_
        ret as long
    wait

Sub FillPart hW, cons, param1, txt$
    CallDLL #user32, "SendMessageA",_
        hW as long, cons as long,_
        param1 as long, txt$ as ptr,_
        FillPart as long
    End Sub


Home

Tip Corner

API Corner

Youth Corner

SpriteByte: Basics

StyleBits 3

Shaped Window

Recursion

Eddie's Lessons

Beginners Programming

Help

Index